package org.py.jwt;

import io.jsonwebtoken.*;
import io.jsonwebtoken.impl.Base64Codec;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.py.common.MessageCode;
import org.py.common.MessageObject;
import org.py.common.MessageUtils;
import org.py.common.until.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.py.jwt.UserToken;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.PrintWriter;
import java.util.Date;

/**
 * Token工具类
 *
 * @author icesane
 */
public class TokenUtil {
    /**
     * 签发JWT
     * userid 用户id
     * json 携带其他信息
     * ttlMillis 过期时间
     */
    public static String createJWT(String userid,String json,long ttlMillis) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        SecretKey secretKey = generalKey();
        IdWorker id = new IdWorker(0, 1);
        JwtBuilder builder = Jwts.builder()
                .setId(String.valueOf(id.nextId()))
                .setSubject(userid+"#"+json)   // 主题
                .setIssuer("icesane")     // 签发者
                .setIssuedAt(now)      // 签发时间
                .compressWith(CompressionCodecs.GZIP)  //数据压缩方式
                .signWith(signatureAlgorithm, secretKey); // 签名算法以及密匙
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            Date expDate = new Date(expMillis);
            builder.setExpiration(expDate); // 过期时间
        }
        return builder.compact();
    }
    /**
     * 签发JWT
     * json 携带其他信息
     * ttlMillis 过期时间
     */
    public static String createJWT(String json,long ttlMillis) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        SecretKey secretKey = generalKey();
        IdWorker id = new IdWorker(0, 1);
        JwtBuilder builder = Jwts.builder()
                .setId(String.valueOf(id.nextId()))
                .setSubject("#"+json)   // 主题
                .setIssuer("icesane")     // 签发者
                .setIssuedAt(now)      // 签发时间
                .compressWith(CompressionCodecs.GZIP)  //数据压缩方式
                .signWith(signatureAlgorithm, secretKey); // 签名算法以及密匙
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            Date expDate = new Date(expMillis);
            builder.setExpiration(expDate); // 过期时间
        }
        return builder.compact();
    }
    /**
     * 验证JWT
     * @param jwtStr
     * @return
     */
    public static MessageObject validateJWT(String jwtStr) {
        MessageObject messageObject = new MessageObject();
        Claims claims = null;
        try {
            claims = parseJWT(jwtStr);
            messageObject.setCode(MessageCode.M1000);
            messageObject.setContent(claims.getSubject());
        } catch (ExpiredJwtException e) {
            messageObject.setCode(MessageCode.M1004);
            messageObject.setContent("Token过期");
        } catch (SignatureException e) {
            messageObject.setCode(MessageCode.M1003);
            messageObject.setContent("Token验证不通过");
        } catch (Exception e) {
            messageObject.setCode(MessageCode.M1003);
            messageObject.setContent("Token验证不通过");
        }
        return messageObject;
    }

    /**
     * 由字符串生成加密key
     *
     * @return
     */
    public static SecretKey generalKey() {
        byte[] encodedKey = Base64Codec.BASE64.encode(org.py.jwt.SystemConstant.JWT_SECERT).getBytes();
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        return key;
    }

    /**
     *
     * 解析JWT字符串
     * @param jwt
     * @return
     * @throws Exception
     */
    public static Claims parseJWT(String jwt) throws Exception {
        SecretKey secretKey = generalKey();
        return Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(jwt)
                .getBody();
    }
   public static void responseMessage(String json, HttpServletResponse response){
        try {
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/json;charset=utf-8");
            PrintWriter printWriter = response.getWriter();
            printWriter.print(json);
            printWriter.flush();
            printWriter.close();
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }
    public static String getUserid(String content){
        if(StringUtils.isNotEmpty(content)){
            String[] content_split = content.split("#");
            if(content_split[0]!=null&&content_split.length>0&&StringUtils.isNotEmpty(content_split[0])&&StringUtils.isNumeric(content_split[0])){
                return content_split[0];
            }
        }
        return null;
    }

    public static String getServletUserid(){
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String authHeader = request.getHeader("Authorization");
        if(StringUtils.isNotEmpty(authHeader)) {
            String token = authHeader.substring(7);
            if(StringUtils.isNotEmpty(token)) {
                MessageObject messageObject_token = TokenUtil.validateJWT(token);
                String userid = TokenUtil.getUserid(String.valueOf(messageObject_token.getContent()));
                if (StringUtils.isNotEmpty(userid)) {
                    return userid;
                }
            }
        }
        return null;
    }

    public static UserToken getUserToken(){
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String authHeader = request.getHeader("Authorization");
        if(StringUtils.isNotEmpty(authHeader)) {
            String token = authHeader.substring(7);
            if(StringUtils.isNotEmpty(token)) {
                MessageObject messageObject_token = TokenUtil.validateJWT(token);
                String userid = TokenUtil.getUserid(String.valueOf(messageObject_token.getContent()));
                if (StringUtils.isNotEmpty(userid)) {
                    String token_json = TokenUtil.getJson(String.valueOf(messageObject_token.getContent()));
                    UserToken user = (UserToken) MessageUtils.JsonToObject(token_json, UserToken.class);
                    return user;
                }
            }
        }
        return null;
    }
    public static String getJson(String content){
        if(StringUtils.isNotEmpty(content)){
            String[] content_split = content.split("#");
            if(content_split!=null){
                if(content_split.length>1){
                    if(StringUtils.isNotEmpty(content_split[1])) {
                        return content_split[1];
                    }
                }
            }
           // if(content_split[1]!=null&&content_split.length>0&&StringUtils.isNotEmpty(content_split[1])){
             //   return content_split[1];
           // }
        }
        return null;
    }
    public static void main(String[] args) throws InterruptedException {
       /** String subject = "{\"code\":\"1000\",\"content\":[{\"sourcetype\":101,\"userpermis\":[{\"sourcetype\":101,\"userpermid\":101101,\"userpermis\":[{\"sourcetype\":101,\"userpermid\":101101101,\"userpermis\":[{\"sourcetype\":101,\"userpermid\":101101101101,\"userpermisname\":\"批量初始化\"},{\"sourcetype\":101,\"userpermid\":101101101102,\"userpermisname\":\"导入\"},{\"sourcetype\":101,\"userpermid\":101101101103,\"userpermisname\":\"模板下载\"}],\"userpermisname\":\"卡片初始化\"},{\"sourcetype\":101,\"userpermid\":101101102,\"userpermis\":[],\"userpermisname\":\"卡片基础信息\"},{\"sourcetype\":101,\"userpermid\":101101103,\"userpermis\":[],\"userpermisname\":\"用户卡片信息\"},{\"sourcetype\":101,\"userpermid\":101101104,\"userpermis\":[],\"userpermisname\":\"卡务日志\"}],\"userpermisname\":\"卡务管理\"},{\"sourcetype\":101,\"userpermid\":101102,\"userpermis\":[],\"userpermisname\":\"设备管理\"},{\"sourcetype\":101,\"userpermid\":101103,\"userpermis\":[],\"userpermisname\":\"消费配置\"},{\"sourcetype\":101,\"userpermid\":101104,\"userpermis\":[],\"userpermisname\":\"财务管理\"},{\"sourcetype\":101,\"userpermid\":101105,\"userpermis\":[],\"userpermisname\":\"应用对接\"},{\"sourcetype\":101,\"userpermid\":101106,\"userpermis\":[],\"userpermisname\":\"统计分析\"}],\"userpermisname\":\"一卡通\"}],\"current\":10,\"pages\":1,\"pagesize\":1}";
        String sc = "eyJhbGciOiJIUzI1NiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAAACXMsQqAMAwE0H-Ja4ektjHt31TpUAcRUkEQ_92ot907uAvW3iADUZBELDiOjOQT-gAO9Jhtkz-DQVM1aEvVstW3lw6ZIvspCgo7qOf-gd14Eb4flP1LL2AAAAA.rcT1hz4Dgbmfku9i2agwUpgySPu19mzLWpWPZXKw7nc";//createJWT( "123456","{\"code\":\"1212\"}", SystemConstant.JWT_TTL_WEEK);
        System.out.println("****************1"+sc);
      //  System.out.println("****************2"+validateJWT(sc).getErrCode());
      //  System.out.println("****************3"+validateJWT(sc).getClaims().getId());
       // Thread.sleep(3000);
        System.out.println("****************4"+getUserid(String.valueOf(validateJWT(sc).getContent())));
        System.out.println("****************4"+getJson(String.valueOf(validateJWT(sc).getContent())));**/
    }

}